package codeassist.handler;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jface.viewers.StructuredSelection;

import codeassist.ActionContext;
import codeassist.ast.FieldsVisitor;
import codeassist.ast.TypeDeclaratinVisitor;
import codeassist.bean.Field;
import codeassist.util.MethodFinder;

/**
 * 生成toString方法
 * 
 * @author TOBE
 * 
 */
public class ToStringHandler implements Handler, IMethodFinder {

	private ActionContext context;

	private boolean findToString = false;

	public ToStringHandler(ActionContext context) {
		this.context = context;
	}

	@Override
	public void action(Object[] paramArrayOfObject) {
		this.context.getMcs().println("run toStringHandler...");

		if ((this.context.getSelection() != null) && ((this.context.getSelection() instanceof StructuredSelection)) && (!this.context.getSelection().isEmpty())) {

			// 选择的文件,可能是多选
			Iterator<?> it = ((StructuredSelection) this.context.getSelection()).iterator();
			while (it.hasNext()) {
				Object obj = it.next();
				if ((obj instanceof org.eclipse.jdt.core.ICompilationUnit)) {
					org.eclipse.jdt.core.ICompilationUnit cu = (org.eclipse.jdt.core.ICompilationUnit) obj;

					// IProject project = cu.getJavaProject().getProject();
					// IProject project =
					// ResourcesPlugin.getWorkspace().getRoot().getProject("VV");

					// IJavaProject javaProject = JavaCore.create(project);

					IJavaProject javaProject = cu.getJavaProject();
					try {
						// TODO maven这里需要修改
						IFolder srcFolder = javaProject.getProject().getFolder("src");

						if (!srcFolder.exists()) {
							srcFolder.create(true, true, null);
						}

						// 取某个java源代码,加入内容
						// eclipse创建代码
						// IPackageFragmentRoot packageFragmentRoot =
						// javaProject.findPackageFragmentRoot(srcFolder.getFullPath());

						// IPackageFragment packageFragment =
						// packageFragmentRoot.getPackageFragment("ast");

						// IFile codefile =
						// srcFolder.getFile("/ast/PluginAddCodeTest.java");
						// IFile codefile = srcFolder.getFile(cu.getPath());
						IFile codefile = ResourcesPlugin.getWorkspace().getRoot().getFile(cu.getPath());
						// 取得代码

						// CompilationUnit comp =
						// JdtAstUtil.getCompilationUnit(codefile.getFullPath().toString());

						InputStream codeins = codefile.getContents();
						ASTParser parser = ASTParser.newParser(AST.JLS4);

						StringBuilder sb = new StringBuilder();// 读入代码
						BufferedReader br = new BufferedReader(new InputStreamReader(codeins));
						String readLine = null;
						// toString方法只会有一个return
						while (null != (readLine = br.readLine())) {
							if (!findToString && MethodFinder.match(readLine, "toString")) {
								findToString = true;
								// 已经有该方法了,则覆盖
							}
							
							if (readLine.trim().startsWith("return")) {
								
							}
							
//							if (!findToString)
								sb.append(readLine).append("\n");
						}

						codeins.close();
						br.close();

						String oldcode = sb.toString();

						// 使用AST分析代码,取得字段信息
						parser.setSource(oldcode.toCharArray());
						parser.setKind(ASTParser.K_COMPILATION_UNIT);
						CompilationUnit comp = (CompilationUnit) parser.createAST(null);

						// 使用visitor获得TypeDeclaration
						TypeDeclaratinVisitor typeDeclaratinVisitor = new TypeDeclaratinVisitor();
						comp.accept(typeDeclaratinVisitor);
						TypeDeclaration classDec = typeDeclaratinVisitor.getTc();

						if (null == classDec) {
							context.getMcs().println("类文件格式有问题, 找不到 TypeDeclaration");
						}
						
						FieldsVisitor fieldsVisitor = new FieldsVisitor();
						comp.accept(fieldsVisitor);
						List<Field> fieldList = fieldsVisitor.getFieldList();
						
						
						int endIndex = sb.lastIndexOf("}");// 结束符,从结束符开始添加新代码

						sb.delete(endIndex, sb.length());

						// MessageDialog.openError(context.getShell(), "错误",
						// "该方法已经存在!");

						// 新加的方法,这里是插入标记
//						sb.append("\t/**插件自动生成*/\n");
						// 方法开始
//						sb.append("\tpublic String toString(){");

						// 方法体
						insert(sb, fieldList, false);
						
						// 方法结束
//						sb.append("\n\t}");

						// 类结束
						sb.append("\n}");
						// 这里修改了代码会自动保存
						codefile.setContents(new ByteArrayInputStream(sb.toString().getBytes()), true, false, null);

						// codefile.appendContents(new
						// ByteArrayInputStream(comp.toString().getBytes()),
						// false, false, null);

						// 读取源码,修改后再添加进来,格式会乱,还是用FreeMark,先解析类字段,然后生成代码
						// packageFragment.createCompilationUnit("PluginAddCodeTest.java",
						// comp.toString(), false, new NullProgressMonitor());

						System.out.println(comp.toString());


					} catch (Exception e) {
						this.context.getMcs().print(e.getMessage());
					}

				}
			}

		}

	}

	@Override
	public boolean finded() {
		// 是否包含toString(){}方法
		return findToString;
	}
	
	//插入toString方法
	private void insert(StringBuilder sb, List<Field> fieldList,boolean inserted){
		if(!inserted){
			// 新加的方法,这里是插入标记
			sb.append("\t/**插件自动生成*/\n");
			// 方法开始
			sb.append("\tpublic String toString(){");
		}
		
		//插入方法体
		StringBuffer buf = new StringBuffer("[");
		for(Field f : fieldList){
			if(f.getClassName().equalsIgnoreCase("List")){
				buf.append(f.getName()).append(":{");
				
				if(buf.charAt(buf.length()-1)==',') buf.deleteCharAt(buf.length()-1);
				buf.append("},");
			}else{
				buf.append("//").append(f.getExplain()).append("\n");
				if(f.getClassName().equalsIgnoreCase("int")){
					buf.append(f.getName()).append(":").append(f.getName());
				}
			}
			
			
		}
//		<#list fields as field>
//		<#if field.listType==1>
//		//${field.explain}
//		buf.append("${field.name}:{");
//		for (int i = 0; i < ${field.name}.size(); i++) {
//			<#if field.className=="int">
//			buf.append(${field.name}.get(i) +",");
//			<#elseif field.className=="short">
//			buf.append(${field.name}.get(i) +",");
//			<#elseif field.className=="float">
//			buf.append(${field.name}.get(i) +",");
//			<#elseif field.className=="long">
//			buf.append(${field.name}.get(i) +",");
//			<#elseif field.className=="byte">
//			buf.append(${field.name}.get(i) +",");
//			<#elseif field.className=="String">
//			buf.append(${field.name}.get(i).toString() +",");
//			<#else>
//			buf.append(${field.name}.get(i).toString() +",");
//			</#if>
//		}
//		if(buf.charAt(buf.length()-1)==',') buf.deleteCharAt(buf.length()-1);
//		buf.append("},");
//		<#else>
//		//${field.explain}
//		<#if field.className=="int">
//		buf.append("${field.name}:" + ${field.name} +",");
//		<#elseif field.className=="short">
//		buf.append("${field.name}:" + ${field.name} +",");
//		<#elseif field.className=="float">
//		buf.append("${field.name}:" + ${field.name} +",");
//		<#elseif field.className=="long">
//		buf.append("${field.name}:" + ${field.name} +",");
//		<#elseif field.className=="byte">
//		buf.append("${field.name}:" + ${field.name} +",");
//		<#elseif field.className=="String">
//		if(this.${field.name}!=null) buf.append("${field.name}:" + ${field.name}.toString() +",");
//		<#else>
//		if(this.${field.name}!=null) buf.append("${field.name}:" + ${field.name}.toString() +",");
//		</#if>
//		</#if>
//		</#list>
//		if(buf.charAt(buf.length()-1)==',') buf.deleteCharAt(buf.length()-1);
//		buf.append("]");
//		return buf.toString();
		
		if(!inserted){
			// 方法结束
			sb.append("\n\t}");
		}
	}

}
